#ifndef REQUEST_H_
#define REQUEST_H_

#include "scHeader.h"

namespace sybilpm
{
struct Request
{
	/**
	 * Include  all datasets (SCOPE_TAKEALL) without any restriction.
	 * If followFk is true also all referenced entities (foreign-key
	 * relations) are followed and read.
	 */
	explicit Request(PkType entity, bool followFk = false) :
		rtype(REQU_READ), stype(SCOPE_TAKEALL), entity(entity), followFk(followFk), deadline(0) {}
	/**
	 * Include a full time-slice of entityId (SCOPE_TS).
	 * If followFk is true also all referenced entities (foreign-key
	 * relations) are followed and read.
	 */
	Request(PkType entity, TimeType deadline, bool followFk = false) :
		rtype(REQU_READ), stype(SCOPE_TS), entity(entity), followFk(followFk), deadline(deadline) {}
	/**
	 * Reads all full timeline of an identity (SCOPE_IK) or just a single
	 * object (SCOPE_PK).
	 * If followFk is true also all referenced entities (foreign-key
	 * relations) are followed and read. Foreign keys of timelined or
	 * versioned entities will be followed using iks of the source object
	 * as deadline for the dependent entity. Thus it is not guaranteed
	 * that a full timeline of the dependent entity is read.
	 */
	Request(PkType entity, PkType id, bool followFk, ScopeType scope = SCOPE_IK);
	/**
	 * Read a single dataset from a timelined or versioned entity at a given deadline.
	 */
	Request(PkType entity, PkType id, TimeType deadline, bool followFk = false) :
		rtype(REQU_READ), stype(SCOPE_IKTS), entity(entity), followFk(followFk), deadline(deadline)
		{pks.push_back(id);}
	/**
	 * Construct from XML
	 */
	Request(PkType entity, const QXmlAttributes & attributes);
	/**
	 * Update or insert the given data object in the entity specified.
	 * Note that the data content at the moment of serializing the request
	 * will actually go to the database. You cannot create a snapshot of
	 * a DataObject by creating a write request. If you fire the request
	 * later you will actually write the content in its most recent form,
	 * not as it was when you created the request.
	 */
	Request(PkType entity, PkType pk);

	bool operator==(const Request & that) const;
	void addKey(PkType key);

	RequestType rtype;
	ScopeType stype;
	PkType entity;
	Pks pks;
	bool followFk;
	TimeType deadline; // already in UTC!
	void toXml(QXmlStreamWriter * writer) const;
	void toXmlEntityList(QXmlStreamWriter * writer, bool begin) const;
	void toXmlScope(QXmlStreamWriter * writer, bool writeKeys) const;
	void toXmlData(QXmlStreamWriter * writer) const;
	std::string toString() const;
};

} // namespace sybilpm

namespace std
{
ostream& operator<< (ostream& out, const sybilpm::Request & requ);
}

#endif /* REQUEST_H_ */
